#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;


//字符串的初始化
//字符串是char *的容器 里面帮我们封装好了
void test1()
{
        string  s1 = "aaaa";
        string s2("bbbb");
        string s3  = s2;
        string s4(10, 'a');

        cout<<s1<<endl;
        cout<<s2<<endl; 
        cout<<s3<<endl;
        cout<<s4<<endl;
}

//字符串的遍历
void test2()
{
        string s = "abcdefg";
        //1.数组方式
        for (int i = 0; i < s.length(); i++)
        {
                cout<<s[i]<<" ";
        }
        cout<<endl;
        //2.迭代器方式
        for ( string::iterator it = s.begin(); it != s.end(); it++ )
        {
                cout<<*it<< " ";
        }
        cout<<endl;

        try
        {
                //3. at[]和operator[]一样, 区别是会抛出异常
                for (size_t i = 0; i < s.length()+3; i++)
                {
                        cout<<s.at(i)<<" ";
                }
                cout<<endl;
        }
        catch(const std::exception& e)
        {
                std::cerr << e.what() << '\n';
        }
}

//字符指针和string的转换
void test3()
{
        string s = "aaa nbbb";

        //1 将string类中属性的char  * 给露出来
        //也就是string转换为char *
        printf("s:%s\n", s.c_str());//返回内存首地址

        // 2 char * 转换为string

        //3 string的内容拷贝到buf中
        char buf[128] = {0};
        s.copy(buf,  3,  0); //拷贝3个从0开始  注意: 只给你copy 3个字符,不会变成c风格的字符串
        cout<<buf<<endl;
}

//连接字符串
void test4()
{
        string s1 = "aaaa";
        string s2 = "bbbb";
        s1 = s1 + s2;
        cout<<s1<<endl;

        string s3 = "3333";
        string s4 = "4444";
        s3.append(s4);
        cout<<s3<<endl;
}

//字符串的查找和替换
void test5()
{
        string s1 = "wbm hello wbm 111 wbm 222 wbm 333 ";
        //第一次数出现的下标index
        int index  = s1.find("wbm", 0); //位置下标从0开始
        cout<<"index: "<<index<<endl; 

        //案例1 求wbm的次数 每次出现的数组下标
        int offindex = s1.find("wbm", 0);
        while (offindex != string::npos)
        {
                cout<<"offindex:"<<offindex<<endl;
                offindex = offindex+1;
                offindex = s1.find("wbm", offindex);
        }
        
        //案例2 替换 把小写wbm还成大写的WBM
        offindex = s1.find("wbm", 0);
        while (offindex != string::npos)
        {
                cout<<"offindex:"<<offindex<<endl;
                s1.replace(offindex, 3, "WBM");
                offindex = offindex+1;
                offindex = s1.find("wbm", offindex);
        }
        cout<<"s1替换后的结构"<<s1<<endl;

        string s3 = "aaa bbb ccc";
        cout<<s3<<endl;
        s3.replace(0, 3, "AAA");
        cout<<s3<<endl;
}

//截断(区间删除)和插入
void test6()
{
        //截断(区间删除)
        string s1 =  "hello hello2 hello3";
        string::iterator it =  find(s1.begin(), s1.end(), 'l');//find是一个算法
        if(it != s1.end()){
                s1.erase(it);
        }
        cout<<"s1删除l以后的结果:"<<s1<<endl;

        s1.erase(s1.begin(), s1.end());
        cout<<"s1全部删除结果:"<<s1<<endl;
        cout<<"s1的长度:"<<s1.length()<<endl;

        //插入
        string s2 = "BBB";
        s2.insert(0,"AAA"); //头插法
        s2.insert(s2.length(), "CCC");
        cout<<"s2:"<<s2<<endl;
}

//string 算法
void test7()
{
        string s1 = "AAAbbb";
        //函数的入口地址 函数对象 预定义的函数对象
        transform(s1.begin(),  s1.end(), s1.begin(), [](unsigned char c){return toupper(c);}); 
        cout<<"s1: "<<s1<<endl;

        string s2  = "AAAbbb";
        transform(s2.begin(), s2.end(), s2.begin(), [](unsigned char c){return tolower(c);});
        cout<<"s2: "<<s2<<endl;

}

int main(int argc, char const *argv[])
{
        //test1();
        //test2();
        //test3();
        //test4();
        //test5();
        //test6();
        test7();
        return 0;
}
